﻿Imports Aricie.Services
Imports Lucene.Net.Analysis
Imports System.IO
Imports Lucene.Net.Analysis.Tokenattributes

Namespace Aricie.DNN.Modules.LuceneSearch.Business

    Public Class XmlSynonymEngine
        Implements ISynonymEngine

        Dim SynonymsList As New SortedDictionary(Of String, List(Of String))(StringComparer.InvariantCultureIgnoreCase)

        Private Function GetSynonymsList(ByVal xmlSynonymFilePath As String, ByVal subAnalyzer As Analyzer) As SortedDictionary(Of String, List(Of String))

            Dim synonymsList As New SortedDictionary(Of String, List(Of String))(StringComparer.InvariantCultureIgnoreCase)

            Dim wordsGroupsList As New List(Of List(Of String))

            If File.Exists(xmlSynonymFilePath) Then
                Dim streamXml As New StreamReader(xmlSynonymFilePath)
                wordsGroupsList = ReflectionHelper.Deserialize(Of List(Of List(Of String)))(streamXml.ReadToEnd)

                For Each words As List(Of String) In wordsGroupsList
                    For Each word As String In words

                        Dim parsedWord As String = ParseWord(word, subAnalyzer)

                        If Not synonymsList.ContainsKey(parsedWord) Then
                            synonymsList.Add(parsedWord, words)
                        End If
                        If synonymsList.ContainsKey(parsedWord) AndAlso synonymsList(parsedWord) Is Nothing Then
                            synonymsList(parsedWord) = words
                        End If
                    Next
                Next
            End If

            Return synonymsList

        End Function

        Private Function ParseWord(ByVal word As String, ByVal subAnalyzer As Analyzer) As String

            If subAnalyzer IsNot Nothing Then
                Dim stringReader As New StringReader(word.Trim)
                Dim tokenStream As TokenStream = subAnalyzer.TokenStream("defaultFieldName", stringReader)
                Dim sb As New StringBuilder

                Dim termAtt As ITermAttribute = DirectCast(tokenStream.GetAttribute(Of ITermAttribute)(), ITermAttribute)
                While (tokenStream.IncrementToken())
                    sb.Append(termAtt.Term())
                End While

                Return sb.ToString
            Else
                Return word
            End If

        End Function

        Public Sub New(ByVal xmlSynonymFilePath As String, ByVal subAnalyzer As Analyzer)

            SynonymsList = GetSynonymsList(xmlSynonymFilePath, subAnalyzer)

        End Sub

        Public Function GetSynonyms(ByVal word As String) As IEnumerable(Of String) Implements ISynonymEngine.GetSynonyms
            If SynonymsList.ContainsKey(word) Then
                Return SynonymsList(word)
            End If
            Return Nothing
        End Function

    End Class

End Namespace